Indicate Intentions

빌더 클래스로 정의된 경우, 사용자에게 빌더 클래스를 사용해야 함을 알려야 한다.

빌더를 사용하지 않으면, 객체 생성이 불가능하도록 강제한다.
struct HtmlElement{
string name;
string text;
vector<HtmlElement> elements;
const size_t indent_size=2;
// (static )-builder
static unique_ptr<HtmlBuilder> build(const string& root_name){
return make_uniqe<HtmlBuilder>(root_name);
}
protected: //
HtmlElement() {}
HtmlElement(const string& name, const string& text): name(name), text(text) {}
};
//
auto builder=HtmlElement::build("ul");
builder.add_child("li", "hello").add_child("li", "world");
위와 같이 생성자를 숨긴 클래스에 대한 인스턴스를 만들기 위해서는
빌더 클래스를 거쳐서 이를 사용하던지, 팩토리 함수를 통해 빌더의 포인터를 전달 받아서 사용

HtmlBuilder 클래스 내부에 operator HtmlElement()를 구현함으로서,
캐스팅을 이용해서 HtmlElement를 사용할 수 있도록 한다.
struct HtmlBuilder{
operator HtmlElement() const {return root;}
HtmlElement root;
// ...
};
//
HtmlElement e=HtmlElement::build("ul").add_child("li", "hello").add_child("li", "world");
cout<<e.str()<<endl;
operator HtmlElement() 연산자와 별개로
Builder 클래스에 build가 HtmlElement를 반환하도록 할 수도 있다.
HtmlElement HtmlBuilder::build() const {
return root;
}